package com.rfid.project.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import biz.util.*;

import com.rfid.project.model.*;
import com.rfid.project.dao.*;
import com.rfid.project.exception.CannotDelException;
import com.rfid.project.exception.CannotUpdateException;
import com.mysema.query.BooleanBuilder;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javassist.NotFoundException;

import javax.naming.NotContextException;

@Service
@Transactional
public class PeopleService {

	@Autowired
	private PeopleDao peopleDao;

	private QPeople $ = QPeople.people;

	@Autowired
	public void setPeopleDao(PeopleDao peopleDao) {
		this.peopleDao = peopleDao;
	}

	@Autowired
	private ProjectMemberDao projectMemberDao;

	private QProjectMember $_projectMember = QProjectMember.projectMember;

	@Autowired
	public void setProjectMemberDao(ProjectMemberDao projectMemberDao) {
		this.projectMemberDao = projectMemberDao;
	}

	public List<People> findAll() {
		return ListUtil.toList(peopleDao.findAll());
	}
	
	public People findOne(Long id){
		return this.peopleDao.findOne(id);
	}

	public List<People> findAll(String name, String personalTel,
			Long departmentId, String gender, String officeTel, String remark,
			Long positionId, Long technicalTitleId, String username,
			String password, String orderByAttribute) {
		BooleanBuilder condition = new BooleanBuilder();

		if (StringUtil.isNotEmpty(name)) {
			condition.and($.name.contains(name));
		}

		if (StringUtil.isNotEmpty(personalTel)) {
			condition.and($.personalTel.contains(personalTel));
		}

		if (IdUtil.isNotEmpty(departmentId)) {
			condition.and($.department.id.eq(departmentId));
		}

		if (StringUtil.isNotEmpty(gender)) {
			condition.and($.gender.contains(gender));
		}

		if (StringUtil.isNotEmpty(officeTel)) {
			condition.and($.officeTel.contains(officeTel));
		}

		if (StringUtil.isNotEmpty(remark)) {
			condition.and($.remark.contains(remark));
		}

		if (IdUtil.isNotEmpty(positionId)) {
			condition.and($.position.id.eq(positionId));
		}

		if (IdUtil.isNotEmpty(technicalTitleId)) {
			condition.and($.technicalTitle.id.eq(technicalTitleId));
		}

		if (StringUtil.isNotEmpty(username)) {
			condition.and($.username.contains(username));
		}

		if (StringUtil.isNotEmpty(password)) {
			condition.and($.password.contains(password));
		}

		return ListUtil.toList(peopleDao.findAll(condition));
	}
	public List<People> findAll(String name, String personalTel,
			Long departmentId, String gender, String officeTel, String remark,
			Long positionId, Long technicalTitleId, String username,
			String password, Long projectId, String orderByAttribute) {
		BooleanBuilder condition = new BooleanBuilder();
		if (StringUtil.isNotEmpty(name)) {
			condition.and($.name.contains(name));
		}
		
		if (StringUtil.isNotEmpty(personalTel)) {
			condition.and($.personalTel.contains(personalTel));
		}
		
		if (IdUtil.isNotEmpty(departmentId)) {
			condition.and($.department.id.eq(departmentId));
		}
		
		if (StringUtil.isNotEmpty(gender)) {
			condition.and($.gender.contains(gender));
		}
		
		if (StringUtil.isNotEmpty(officeTel)) {
			condition.and($.officeTel.contains(officeTel));
		}
		
		if (StringUtil.isNotEmpty(remark)) {
			condition.and($.remark.contains(remark));
		}
		
		if (IdUtil.isNotEmpty(positionId)) {
			condition.and($.position.id.eq(positionId));
		}
		
		if (IdUtil.isNotEmpty(technicalTitleId)) {
			condition.and($.technicalTitle.id.eq(technicalTitleId));
		}
		
		if (StringUtil.isNotEmpty(username)) {
			condition.and($.username.contains(username));
		}
		
		if (StringUtil.isNotEmpty(password)) {
			condition.and($.password.contains(password));
		}
		if (IdUtil.isNotEmpty(projectId)) {
			BooleanBuilder cond = new BooleanBuilder();
			cond.and(this.$_projectMember.project.id.eq(projectId));
			List<ProjectMember> projectMembers = ListUtil.toList(this.projectMemberDao.findAll(cond));
			Set<Long> ids = new HashSet<Long>();
			for (ProjectMember projectMember : projectMembers) {
				ids.add(projectMember.getPerson().getId());
			}
			condition.and(this.$.id.notIn(ids));
		}
		
		return ListUtil.toList(peopleDao.findAll(condition));
	}
	
	public Page<People> findMyProfile(Long id, String name, String personalTel,
			Long departmentId, String gender, String officeTel, String remark,
			Long positionId, Long technicalTitleId, String username,
			String password, int pageNumber, int pageSize,
			String sortAttribute, String orderDirection) {
		BooleanBuilder condition = new BooleanBuilder();

		if(IdUtil.isNotEmpty(id)){
			condition.and($.id.eq(id));
		}
		
		if (StringUtil.isNotEmpty(name)) {
			condition.and($.name.contains(name));
		}
		if (StringUtil.isNotEmpty(personalTel)) {
			condition.and($.personalTel.contains(personalTel));
		}
		if (IdUtil.isNotEmpty(departmentId)) {
			condition.and($.department.id.eq(departmentId));
		}
		if (StringUtil.isNotEmpty(gender)) {
			condition.and($.gender.contains(gender));
		}
		if (StringUtil.isNotEmpty(officeTel)) {
			condition.and($.officeTel.contains(officeTel));
		}
		if (StringUtil.isNotEmpty(remark)) {
			condition.and($.remark.contains(remark));
		}
		if (IdUtil.isNotEmpty(positionId)) {
			condition.and($.position.id.eq(positionId));
		}
		if (IdUtil.isNotEmpty(technicalTitleId)) {
			condition.and($.technicalTitle.id.eq(technicalTitleId));
		}
		if (StringUtil.isNotEmpty(username)) {
			condition.and($.username.contains(username));
		}
		if (StringUtil.isNotEmpty(password)) {
			condition.and($.password.contains(password));
		}

		Sort sortObject = null;
		if (StringUtil.isEmpty(sortAttribute)) {
			sortObject = new Sort(Direction.DESC, "id");
		} else {
			sortObject = new Sort(Direction.fromStringOrNull(orderDirection),
					sortAttribute);
		}

		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize,
				sortObject);
		return peopleDao.findAll(condition, pageRequest);
	}
	
	
	public Page<People> findAll(String name, String personalTel,
			Long departmentId, String gender, String officeTel, String remark,
			Long positionId, Long technicalTitleId, String username,
			String password, int pageNumber, int pageSize,
			String sortAttribute, String orderDirection) {
		BooleanBuilder condition = new BooleanBuilder();

		if (StringUtil.isNotEmpty(name)) {
			condition.and($.name.contains(name));
		}
		if (StringUtil.isNotEmpty(personalTel)) {
			condition.and($.personalTel.contains(personalTel));
		}
		if (IdUtil.isNotEmpty(departmentId)) {
			condition.and($.department.id.eq(departmentId));
		}
		if (StringUtil.isNotEmpty(gender)) {
			condition.and($.gender.contains(gender));
		}
		if (StringUtil.isNotEmpty(officeTel)) {
			condition.and($.officeTel.contains(officeTel));
		}
		if (StringUtil.isNotEmpty(remark)) {
			condition.and($.remark.contains(remark));
		}
		if (IdUtil.isNotEmpty(positionId)) {
			condition.and($.position.id.eq(positionId));
		}
		if (IdUtil.isNotEmpty(technicalTitleId)) {
			condition.and($.technicalTitle.id.eq(technicalTitleId));
		}
		if (StringUtil.isNotEmpty(username)) {
			condition.and($.username.contains(username));
		}
		if (StringUtil.isNotEmpty(password)) {
			condition.and($.password.contains(password));
		}

		Sort sortObject = null;
		if (StringUtil.isEmpty(sortAttribute)) {
			sortObject = new Sort(Direction.DESC, "id");
		} else {
			sortObject = new Sort(Direction.fromStringOrNull(orderDirection),
					sortAttribute);
		}
		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize, sortObject);
		return peopleDao.findAll(condition, pageRequest);
	}

	public People getPeople(Long id) {
		return peopleDao.getOne(id);
	}

	public void deletePeople(Long id) {
		peopleDao.delete(id);
	}

	public void savePeople(People people) throws CannotDelException {
		if (null == people.getId() && this.findPeopleByUsername(people.getUsername())) {
			throw new CannotDelException("该用户已存在");
		} else {
			peopleDao.save(people);
		}
	}
	
	
	private boolean findPeopleByUsername(String username) {
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.username.eq(username));
		return this.peopleDao.count(condition) > 0;
	}
	
	public People login(People people) throws NotContextException, NotFoundException{
		BooleanBuilder condition = new BooleanBuilder();
		condition.and($.username.eq(people.getUsername()));
		if(this.peopleDao.count(condition) < 1){
			throw new NotFoundException("账号不存在！");
		}else{
			condition.and($.password.eq(people.getPassword()));
			People currentPeople = this.peopleDao.findOne(condition);
			if (null == currentPeople) {
				throw new NotContextException("密码错误！");
			} else {
				return currentPeople;
			}
		}
	}

	public List<People> findByPosition(long positionId) {
		BooleanBuilder condition = new BooleanBuilder();
		condition.and(this.$.position.id.eq(positionId));
		return ListUtil.toList(this.peopleDao.findAll(condition));
	}

	public List<People> findByPostionIds(Long... statuses) {
		BooleanBuilder condition = new BooleanBuilder();
		condition.and(this.$.position.id.in(statuses));
		return ListUtil.toList(this.peopleDao.findAll(condition));
	}

	public void changePwd(Long id, String password) throws CannotUpdateException {
		if(IdUtil.isEmpty(id) || StringUtil.isEmpty(password)){
			throw new CannotUpdateException("数据不合法，不能修改！");
		}
		People people = this.peopleDao.findOne(id);
		people.setPassword(password);
		//this.peopleDao.save(people);
	}

}
